{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# Copyright 2016-present, Facebook, Inc.\n",
    "# All rights reserved.\n",
    "\n",
    "# This source code is licensed under the license found in the\n",
    "# LICENSE-examples file in the root directory of this source tree."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Intro to Sampling\n",
    "\n",
    "The question we will ask is: **Given a population, what percent of the population is a positive example?**\n",
    "\n",
    "*This assumes that we don't know if something is positive or negative in advice!* If we know the answer to this up front or it is easily understood then there is no point in sampling. We have to take the sample because we are interested in identifying some attribute but the evaluation is expensive.\n",
    "\n",
    "First we will demonstrate how this code can be used to take a normal random sample.\n",
    "\n",
    "Then, we will study our question when the importance weight of each record is different:\n",
    "1. Using regular random sampling\n",
    "1. Using importance weighted sampling\n",
    "1. Using full model assisted sampling"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "import ml_sampler\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## The population"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "population_size = 1000000\n",
    "\n",
    "# 1.0% of the population is a 'positive' example\n",
    "is_positive = np.random.random(population_size) < 0.01\n",
    "\n",
    "# Note: predetermining 'is_positive' is necessary for \n",
    "# the purposes of this example.\n",
    "# In a real application we would have to sample - then determine\n",
    "# if the record is positive or not. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Prevalence 1.0036\n"
     ]
    }
   ],
   "source": [
    "print 'Prevalence', is_positive.sum() * 100.0 / len(is_positive) "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Simple random sampling using ml_sampler"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Est. Positive Percent 0.85\n"
     ]
    }
   ],
   "source": [
    "random_weights = np.ones(population_size)\n",
    "random_biases = np.ones(population_size)\n",
    "\n",
    "random_index, random_p_sample = ml_sampler.biased_sample(\n",
    "    biases=random_biases, # same bias for each record (no bias)\n",
    "    weights=random_weights, # weight each record equally\n",
    "    num_samples=2000\n",
    ")\n",
    "\n",
    "\n",
    "est_pos_volume = ml_sampler.estimator(\n",
    "    random_weights[random_index], \n",
    "    random_p_sample, \n",
    "    is_positive[random_index],\n",
    ")\n",
    "\n",
    "print 'Est. Positive Percent', est_pos_volume * 100.0 / len(is_positive)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Sampling with importance weights!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# assign different weights to each record. \n",
    "# for example, if we cared about the overall prevalence of spam - \n",
    "#    this could represent number of times a piece of potential spam was seen  \n",
    "importance_weights = np.random.exponential(scale=100, size=population_size)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Weighted Prevalence 0.993855046356\n"
     ]
    }
   ],
   "source": [
    "weighted_pos_volume = importance_weights[is_positive].sum()\n",
    "\n",
    "print 'Weighted Prevalence', weighted_pos_volume * 100.0 / importance_weights.sum()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Random Sampling"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Est. Weighted Prevalence 0.761555654195\n"
     ]
    }
   ],
   "source": [
    "# do regular random sampling then sum the importance weights at the end\n",
    "# this is similar to the above example but now we have to account for importance\n",
    "\n",
    "random_sample_index, random_sample_p_sample = ml_sampler.biased_sample(\n",
    "    # same bias for each record\n",
    "    biases=np.ones(population_size), \n",
    "    weights=np.ones(population_size),\n",
    "    num_samples=2000\n",
    ")\n",
    "\n",
    "# represents the size of each record, we didn't account for this in the sampling process\n",
    "random_sample_weight = importance_weights[random_sample_index]\n",
    "random_sample_is_positive = is_positive[random_index]\n",
    "\n",
    "est_pos_volume = ml_sampler.estimator(\n",
    "    random_sample_weight, \n",
    "    random_sample_p_sample, \n",
    "    random_sample_is_positive,\n",
    ")\n",
    "\n",
    "print 'Est. Weighted Prevalence', est_pos_volume * 100.0 / importance_weights.sum()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Probability Proportionate to Size (PPS) Sampling / Weighted sampling"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Est. Weighted Prevalence 1.2\n"
     ]
    }
   ],
   "source": [
    "pps_index, pps_p_sample = ml_sampler.biased_sample(\n",
    "    # same bias for each record\n",
    "    biases=np.ones(population_size), \n",
    "    # now we sample with our importance weights\n",
    "    weights=importance_weights,\n",
    "    num_samples=2000\n",
    ")\n",
    "\n",
    "pps_weights = importance_weights[pps_index]\n",
    "pps_is_positive = is_positive[pps_index]\n",
    "\n",
    "est_pos_volume = ml_sampler.estimator(\n",
    "    pps_weights, \n",
    "    pps_p_sample,\n",
    "    pps_is_positive,\n",
    ")\n",
    "\n",
    "print 'Est. Weighted Prevalence', est_pos_volume * 100.0 / importance_weights.sum()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Cool story. \n",
    "\n",
    "But why should you care about PPS Sampling vs the Regular sampling? \n",
    "\n",
    "Well, it turns out that these two methods are NOT equal. The PPS sampling method is generally better because it produces a more accurate estimate - the error of the samples taken is less.\n",
    "\n",
    "Lets do some simulations to prove this out!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "random_prevalence = []\n",
    "for _ in range(3000):\n",
    "    random_sample_index, random_sample_p_sample = ml_sampler.biased_sample(\n",
    "        # same bias for each record\n",
    "        biases=np.ones(population_size), \n",
    "        weights=np.ones(population_size),\n",
    "        num_samples=2000\n",
    "    )\n",
    "\n",
    "    # represents the size of each record, we didn't account for this in the sampling process\n",
    "    random_sample_weight = importance_weights[random_sample_index]\n",
    "    random_sample_is_positive = is_positive[random_sample_index]\n",
    "\n",
    "    est_pos_volume = ml_sampler.estimator(\n",
    "        random_sample_weight, \n",
    "        random_sample_p_sample, \n",
    "        random_sample_is_positive,\n",
    "    )\n",
    "    \n",
    "    prevalence = est_pos_volume * 100.0 / importance_weights.sum()\n",
    "    \n",
    "    random_prevalence.append(prevalence)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "pps_prevalence = []\n",
    "for _ in range(3000):\n",
    "    pps_index, pps_p_sample = ml_sampler.biased_sample(\n",
    "        # same bias for each record\n",
    "        biases=np.ones(population_size), \n",
    "        # now we sample with our importance weights\n",
    "        weights=importance_weights,\n",
    "        num_samples=2000\n",
    "    )\n",
    "\n",
    "    pps_weights = importance_weights[pps_index]\n",
    "    pps_is_positive = is_positive[pps_index]\n",
    "\n",
    "    est_pos_volume = ml_sampler.estimator(\n",
    "        pps_weights, \n",
    "        pps_p_sample,\n",
    "        pps_is_positive,\n",
    "    )\n",
    "    \n",
    "    prevalence = est_pos_volume * 100.0 / importance_weights.sum()\n",
    "    \n",
    "    pps_prevalence.append(prevalence)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Random estimate of weighted prevalence 0.96\n",
      "\t95% confidence interval (0.46, 1.68)\n",
      "\n",
      "PPS estimate of weighted prevalence 1.00\n",
      "\t95% confidence interval (0.60, 1.45)\n"
     ]
    }
   ],
   "source": [
    "print 'Random estimate of weighted prevalence {0:0.2f}'.format(np.percentile(random_prevalence, 50))\n",
    "print '\\t95% confidence interval ({0:0.2f}, {1:0.2f})'.format(*np.percentile(random_prevalence, [2.5, 97.5]))\n",
    "print\n",
    "print 'PPS estimate of weighted prevalence {0:0.2f}'.format(np.percentile(pps_prevalence, 50))\n",
    "print '\\t95% confidence interval ({0:0.2f}, {1:0.2f})'.format(*np.percentile(pps_prevalence, [2.5, 97.5]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Ahhh! So we see that the importance estimate typically produces narrower confidence intervals. \n",
    "\n",
    "**Question?** Can we do any better than this?\n",
    "\n",
    "**Answer?** Well, it depends. With importance sampling we were able to take into account the additional information we had about the importance values up front. What if we also had some approximate information about the chances of something being positive? We should be able to use that information too. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Model Assisted Sampling\n",
    "Lets say that we have some additional information for each record. For example, suppose we know up front the probability that a record will be positive (but not specifically if it IS positive). We can use this information to our advantage. \n",
    "\n",
    "In practice we may build a machine learning model that produces scores for each record (does not actually have to be a true probability). We can use this new information to our advantage!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# create some scores for each record where the score is correlated\n",
    "# with is_positive - this is a stand in for a real ML model\n",
    "scores = np.zeros(population_size)\n",
    "scores[is_positive] = np.random.normal(loc=2.9, scale=0.3,\n",
    "                                       size=is_positive.sum())\n",
    "\n",
    "scores[~is_positive] = np.random.normal(loc=0.8, scale=1.0,\n",
    "                                        size=(~is_positive).sum())\n",
    "scores -= scores.min() \n",
    "scores += 0.0001"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.text.Text at 0x7faaf6bf39d0>"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\nKDgSERERSSg4EhEREUkoOBIRERFJKDgSERERSSg4EhEREUkoOBIRERFJKDgSERERSSg4EhEREUko\nOBIRERFJKDgSERERSSg4EhEREUkoOBIRERFJKDgSERERSSg4EhEREUkoOBIRERFJKDgSERERSSg4\nEhEREUkoOBIRERFJKDgSERERSSg4EhEREUkoOBIRERFJKDgSERERSSg4EhEREUkoOBIRERFJKDgS\nERERSSg4EhEREUkoOBIRERFJKDgSERERSSg4EhEREUkoOBIRERFJbNGfTGa2NXA8MCX+e38s63R3\nv61CnknA5cAHgJHAPODr7n5rH/WcA5wD7A70Ao8CF7v7vArpx8Y6jgHGAx3A/wCfd/d1FfIcDnwW\n2B/YGng+pn+gQvotgH8CPg7sAnQCD8Z2La70s4iIiEhz6G/P0dHAzcDfA/sSAqMi8Ntyic3seOBJ\n4DhgNvAIYMBNZnZShTy3A/8B7AA8ACwgBD0/N7MRZdLvBvwG+DSwHLifEOxcBlxXoY5PAw8BhwKz\n4r8DgJ+Y2V+WST8MeBi4ChgR61gBnAY8YGbqiRMREWly/X0zbwG+SghWLJ5bA7xQmtDMdiEEUt3A\nYe4+3d3/GvgEkCMEL6V5ZgInA48Bu7r7ycA+hMBkPHBmSfpW4E5gAnCRu0929xOBg2K9nzCzbUvy\nHAxcQ+hdmuTux7r7EcDnCcHeZ8v83NcAHwLuStq1NzCH0Hs2o8L9EhERkSbRr+DI3e9y98vd/afA\ne+Ppue7eWyb5V4CtgCvc/fHk/G2EwGUfM9sqO2lmo4DPEYarTnX3lbHOIvB9QkB1SEkd5wATgXvd\n/dqknS8DTxCCnSklea4h/Pznu3sa1N0cj++ow8z2BD4JLATOdvfuWMcaQrBUrl0iIiLSZOoxDLRP\nPG4wpGZmOwMfBVYC30mvuXsPsCx+Oz65dAHQDtzu7gtLilwUjxNKzl9MGNa7ukz7NshjZlMJw2fz\n3f3HFdKPivOLMpfE443uvqrKdomIiEiTqVdwVASeK3PtpFjHD929s8z1tnjMl+QpArdUk97MDgB2\nAl4r6Znqq45Tqqjj7TwxSDo2nquqXSIiItKc+rVarUTWc1QuODqGEIQ8bGbbAbcSelnOJgxDvSem\nWw5vz0/aA3gLeNLMjiWsPvt3d78D2DZNH30kHh+KZdwIvA/4uLsvqpDnmHh82Mx2Bb4L/MrdZybp\nV8chM4Cpsa0vuvsCMzs3/gyXuPujFeoQERGRJrRJPUdmlgf2jN8+V+ba/vHbRwk9QtOAM4DJhAAm\nD3Sxfngtmxc0Ky69/2fC8NcV8fzu8fiHpKophADsl8m8oMOA08vlMbPtge0JE8ifIsxX+iBwcQzg\nKtWR/RwAX4ztyobado9tSPOIiIhIE9rUniMjDCm95u5/Lrm2BzAMWOHuC83sIeA1Qs/R86xf2fVc\nnGwNMCke58bjLbGOm+L3EwlByNNJPVmeOYS9k35BCLzuM7PRwDhgHevnRGXp3d17zeweQsA2y92X\nmtnEeL20jmLSru8B5xImiGftKs1TlXxeq/9rkd0v3bcgn28hl8vR0pKrmCa71leaVC6XI5erPv27\nrcx8voUttmjRa60fdM/6R/etdpv7Xm1qcNTXkFq2im0egLu/BOycXYyToiH03qR5isCLMc/1wPUx\nfQthA8m388R9h7bN8sQVZIcndZwQv/ydu68uaVdWxyxCAJWZGssrbVeaZyYwM9YxmhAI9gK/LnMf\n+jRiRKHWLILuW6azsx1opVDYcqNp29paqypz2LBW2tqoqsxqNUuZhUIrhUI7I0e+vYBWr7V+0D3r\nH923waMewVGlydgj47HSPJyjYt57q8xzIGHezwJ3n12Sfq27d5XJMy3W8ZNq6oj7JX0oflttu44k\nzJ96wt1XlLnepzff7KKnp9wOCFJOPt/CiBEF3bdoxYpO2tq66epaWzFNS0uOtrZW1qzppre3WDFd\nZvXqblpb6bPMWjVLmV1d3axZ00l7+yq91vpB96x/dN9ql92zzWVz9hxl/8OrSy+Y2RRgN8IGjI9W\nkwc4Kx7vrLKOYYR5TgB3V1nHicBw4Dfu/koN7SqWtKtqPT29rFunX4Za6b4FPT29FIvFqoKe3t7q\n0hWLRYpFqkpbrWYqs/S1pdda7XTP+kf3bfDY1EG7inscETZLhHcOWWUuJAQU15RsHFk2j5mNAU4F\n1gLfSC4ti+dGxGAodTawDfCgu/+uynZ9hvL7JVVq197AEcDrrJ8XJSIiIk2s38FRDFjGAW+5+/wy\nSZ4m9LRMNrO9knx/R+ihmUecT5R4nDBEdXq2AWMMem4l7LJ9tbv/MUscN5LM5gZlPUuY2X7Al2L9\n2YqyzBPxON3MxiV5vkBYgfY4Ycfrcu06M0k/KrYrB1xeYR8nERERaTI1DauZ2ZmEVVoQghWAVjOb\nFb9+3d1nALh7p5ldD1wEPGFmjxCCqSmEFWsnlAko7iAs2z8YeN7Mno9fjyfMG7qCDX2N8NiOb5rZ\ncYRHkkwjDIWdVdJrhLvPN7O7gROA58zsl4QhvvcDDpyWrJ7L3Aj8A3ByfMDtfMLE722Ab7n7d/u4\nbSIiItJEau05mkaYGH0gsBdhCKotOVe6HGYmcCVhIvOHCUHODcAB7j6ntPAYLB0K3AOMBaYDi4Hz\n3P34cs9uc/f7CTtezyZMpp5MmEx9iLv/oMLPcQZwHSGQmgEUCM+Am+LufypTxyLCKraHgV0Jk7Dn\nEJ79dkGFOkRERKQJ1dRz5O6nAafVkL5I2DDxizXkeY0w7FZLu+7mnZOuN5Z+NWHe04U15JkNHF1L\nu0RERKT5aMcpERERkUQ9nq0mIlXo6elhyZKOupbZ0dHBjjvWbym7iIgoOBIZMEuWdLBq1VWMHt1e\ntzK7upbS2VkARtStTBGRoU7BkcgAGj26nQkThtetvMWL36pbWSIiEmjOkYiIiEhCwZGIiIhIQsGR\niIiISELBkYiIiEhCwZGIiIhIQsGRiIiISELBkYiIiEhCwZGIiIhIQsGRiIiISELBkYiIiEhCjw8R\nEYl6enrp6AgPB87nW+jsbGfFik56eno3qdwxY8aSz+fr0UQRGQAKjkREoqVLO2lpuYFCYTtyuRzQ\nSltbN8Visd9lLlvWyZIlMxk/fkL9Gioim5WCIxGRxKhRBSZMGE5LS45CYUu6utbS29v/4Aigq6tO\njRORAaE5RyIiIiIJBUciIiIiCQVHIiIiIgkFRyIiIiIJBUciIiIiCQVHIiIiIgkFRyIiIiIJBUci\nIiIiCQVHIiIiIgkFRyIiIiIJBUciIiIiCQVHIiIiIgkFRyIiIiIJBUciIiIiCQVHIiIiIgkFRyIi\nIiIJBUciIiIiCQVHIiIiIgkFRyIiIiIJBUciIiIiCQVHIiIiIgkFRyIiIiIJBUciIiIiCQVHIiIi\nIgkFRyIiIiIJBUciIiIiCQVHIiIiIgkFRyIiIiKJLQaqIjO7EriiwuUiMMndZ5fkmQRcDnwAGAnM\nA77u7rf2Uc85wDnA7kAv8ChwsbvPq5B+bKzjGGA80AH8D/B5d19XIc/hwGeB/YGtgedj+gcqtUtE\nRESaw4AFR8C+hCDoTqCr5FoP8Lv0hJkdD9xGaOPPYpojgZvMbLW731VagZndDpwMLAEeIARIxwD7\n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\nr2uZIrKegiMRkc1o6dJOWlpuoFDYri7lLVvWyZIlMxk/fkJdyhORDSk4EhHZzEaNKtRt1SNAV1fd\nihKRMjTnSERERCSh4EhEREQkoeBIREREJKHgSERERCSh4EhEREQkoeBIREREJKHgSERERCSh4EhE\nREQkoeBIREREJKHgSERERCSh4EhEREQkoeBIREREJKHgSERERCSh4EhEREQkoeBIREREJKHgSERE\nRCSh4EhEREQkoeBIREREJKHgSERERCSh4EhEREQkoeBIREREJKHgSERERCSh4EhEREQkoeBIRERE\nJLFFoxsgUg89PT0sWdJR1zI7OjrYccdiXcsUEZHBT8GRvCssWdLBqlVXMXp0e93K7OpaSmdnARhR\ntzJFRGTwU3Ak7xqjR7czYcLwupW3ePFbdStLRESah4IjEZEm0tPTS0dHfYeQAcaMGUs+n697uSLN\nSMGRiEgTWbq0k5aWGygUtqtbmcuWdbJkyUzGj59QtzJFmpmCIxGRJjNqVKGuQ8gAXV11LU6kqWkp\nv4iIiEhCwZGIiIhIQsNq/WBmWwOXAicCOwArgHuAS919ZSPbJiIiIptGPUc1MrPtgF8BlwG9wH3x\n+Cng9gY2TUREROpAPUe1uxnYA7jO3S8EMLORgAPTzWyiu89uZANFZPDo7u5hzpw3ePPN+pT3wgvL\nmDRpZH0KE5GyFBzVwMz+CpgOPAtclJ139zfM7D7gb4FDAAVHIgLASy+9wbd+9BcMH7VDXcpb+foC\nPrvVfPbc8711KU9ENqTgqDaXAEXgGncvfejWIiAHaKOQjdiU56Dl8y10drazYkUnPT29b5/Xc9Bk\nMBs+age2GbdrXcrq7VnHyy8/w9NPL6pLeQBLl65ip53W1q08kWan4KhKZjaW0Cu0GrirTJI2QuCk\nLWY3YlOeg5bL5YBW2tq6KRbXB0N6DpoMFatWLOJHT+7H/3p9eqIg9EZ9YsaTtLZuuUnllH540a7b\n0qwUHFVvBmEC+2PuvsbMrgSOBM519znAtjHd8ga1r6n09zloLS05CoUt6epaS2/v+uBIz0GToaSe\nPVGZXO5uCoXnN7GM9R9eli5dpV23pWkpOKreFELP0KNm1g5cEb8/Dzgf2D2m+0NjmicimyqdPJ3L\nwbBhraxe3U1xE0ZsX311Rf0auBlts03bJu+6nX54KRaL2nVbmpaCo+pNise57t5pZncQeo7uMrMc\n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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7faaf74e0450>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "scores_df = pd.DataFrame({'scores': scores, 'is_positive': is_positive})\n",
    "\n",
    "bins = np.linspace(scores.min(), scores.max(), 20)\n",
    "\n",
    "ax = scores_df[~scores_df.is_positive].scores.hist(label='Negative', alpha=0.5, bins=bins, color='yellow')\n",
    "scores_df[scores_df.is_positive].scores.hist(ax=ax, label='Positive', alpha=1.0, bins=bins)\n",
    "\n",
    "plt.legend()\n",
    "plt.title('Histogram of positive\\nand negative example scores')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "ml_index, ml_p_sample = ml_sampler.biased_sample(\n",
    "\n",
    "    # Bias the sample towards according to scores. This method will\n",
    "    # over sample things with higher scores but those\n",
    "    # samples will be weighted less.\n",
    "    # Example:\n",
    "    #     scores[1] == 10\n",
    "    #     scores[2] == 1\n",
    "    #   All else being equal:\n",
    "    #    record[1] should be sampled 10x more frequently than record[2]\n",
    "    #    record[1] will count for 1/10th the weight of record[2]\n",
    "    biases=scores, \n",
    "    \n",
    "    weights=importance_weights, \n",
    "    num_samples=2000\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Est. Weighted Prevalence 0.922674719857\n",
      "Percent of Positive Samples Taken 1.3\n"
     ]
    }
   ],
   "source": [
    "ml_is_positive = is_positive[ml_index]\n",
    "ml_weights = importance_weights[ml_index]\n",
    "\n",
    "est_pos_volume = ml_sampler.estimator(\n",
    "    ml_weights, \n",
    "    ml_p_sample,\n",
    "    ml_is_positive,\n",
    ")\n",
    "\n",
    "print 'Est. Weighted Prevalence', est_pos_volume * 100.0 / importance_weights.sum()\n",
    "\n",
    "# We get ~50% more positive samples with ml_sampler\n",
    "print 'Percent of Positive Samples Taken', ml_is_positive.mean() * 100.0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "ml_prevalence = []\n",
    "\n",
    "for _ in range(3000):\n",
    "    ml_index, ml_p_sample = ml_sampler.biased_sample(\n",
    "        biases=scores,  \n",
    "        weights=importance_weights,         \n",
    "        num_samples=2000\n",
    "    )\n",
    "    \n",
    "    ml_is_positive = is_positive[ml_index]\n",
    "    ml_weights = importance_weights[ml_index]\n",
    "\n",
    "    est_pos_volume = ml_sampler.estimator(\n",
    "        ml_weights, \n",
    "        ml_p_sample,\n",
    "        ml_is_positive,\n",
    "    )\n",
    "    \n",
    "    prevalence = est_pos_volume * 100.0 / importance_weights.sum()\n",
    "    \n",
    "    ml_prevalence.append(prevalence)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Random estimate of prevalence 0.96\n",
      "\t95% confidence interval (0.46, 1.68)\n",
      "\n",
      "PPS estimate of prevalence 1.00\n",
      "\t95% confidence interval (0.60, 1.45)\n",
      "\n",
      "ML estimate of prevalence 0.98\n",
      "\t95% confidence interval (0.66, 1.36)\n",
      "\n"
     ]
    }
   ],
   "source": [
    "print 'Random estimate of prevalence {0:0.2f}'.format(np.percentile(random_prevalence, 50))\n",
    "print '\\t95% confidence interval ({0:0.2f}, {1:0.2f})'.format(*np.percentile(random_prevalence, [2.5, 97.5]))\n",
    "print\n",
    "\n",
    "print 'PPS estimate of prevalence {0:0.2f}'.format(np.percentile(pps_prevalence, 50))\n",
    "print '\\t95% confidence interval ({0:0.2f}, {1:0.2f})'.format(*np.percentile(pps_prevalence, [2.5, 97.5]))\n",
    "print\n",
    "\n",
    "print 'ML estimate of prevalence {0:0.2f}'.format(np.percentile(ml_prevalence, 50))\n",
    "print '\\t95% confidence interval ({0:0.2f}, {1:0.2f})'.format(*np.percentile(ml_prevalence, [2.5, 97.5]))\n",
    "print\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Analysis\n",
    "Random, Importance, and ML all produce reasonable estimations of the true prevalence. In this example - ML Assisted  has the tightest confidence interval and is more accurate than the other methods. Additionally, ML Assisted gives us ~50% more positive samples."
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python [default]",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
